﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using Odyssey.Controls;
using System.Collections.ObjectModel;
using System.Collections.Generic;
using System.Collections;
using Odyssey.Utils;
using System.Linq;
using System.Windows.Data;

namespace Odyssey.ViewModels
{


    /// <summary>
    /// Maintains a grouped collection.
    /// </summary>
    /// <typeparam name="T">Type of item. Must implement IGroupItem.</typeparam>
    public class GroupedDataSource<T> : DataSourceBase<T>
        where T : IGroupItem
    {
        public GroupedDataSource()
            : base()
        {
        }

        public GroupedDataSource(IEnumerable<T> items, IComparer<T> comparer = null, Func<T, bool> filter = null)
            : base(items, comparer, true, filter)
        {
        }

        /// <summary>
        /// Gets or sets the name of the property on an item which specifies grouping.
        /// This value is being used to determine if an item needs to be reordered when one of it's property changes.
        /// </summary>
        public string GroupPropertyName { get; set; }

        protected override string GetGroupName(T item)
        {
            return item.GroupName ?? string.Empty;
        }



        /// <summary>
        /// Populates the View from a given collection.
        /// </summary>
        /// <param name="items">Collection to populate.</param>
        /// <param name="comparer">Comparer used to compare two items of the collection.</param>
        protected override void Populate(IEnumerable<T> items, IComparer<T> comparer)
        {
            var filter = Filter;

            if (CanNotify)
            {
                foreach (var item in items) PrepareItem(item);
            }

            if (filter != null) items = items.Where(x => filter(x));

            var groups = from item in items
                         group item by item.GroupName into grp
                         orderby grp.Key
                         select grp;


            if (comparer == null) comparer = Comparer<T>.Default;
            foreach (var g in groups)
            {
                GroupItem group = new GroupItem(g.Key);
                Groups.Add(g.Key, group);
                Items.Add(group);
                int cnt = 0;
                foreach (var item in g.OrderBy(x => x, comparer))
                {
                    cnt++;
                    Items.Add(item);
                }
                group.ChildCount = cnt;
            }
        }

        protected override bool HasOrderChanged(string propertyName)
        {
            return propertyName == "Name" || propertyName == GroupPropertyName;
        }

    }

}
